//import com.nesium.controls.ScrollingTextField;
import com.nesium.utils.Delay;
import com.nesium.Event;
import mx.core.UIComponent;
import mx.controls.Button;
import mx.utils.Delegate;
import mx.events.EventDispatcher;


class MP3Player extends UIComponent
	// v1.30
{

	private	var titleTxt				: MovieClip;
	private	var timeTxt					: TextField;
	
	private	var sndContainer		: MovieClip;
	private	var controlBtn			: MovieClip;
	private	var barLoad					: MovieClip;
	private	var barPos					: MovieClip;
	private	var volumeBarBtn		: MovieClip;
	private	var volumeBar				: MovieClip;
	private	var dlBtn						: Button;	
	private	var toggleTimeBtn		: Button;
	private	var loopBtn					: Button;
	
	private	var updateInt				: Number 		= 0;
	
	private	var sndUrl					: String;
	private	var snd							: Sound;
	private	var lastPos					: Number;
	private	var soundLoaded			: Boolean 	= false;
	private	var showTotalTime		: Boolean		= false;
	private	var loadProgress		: Number		= 0;
	private	var vol							: Number		= 100;
		
	private	var pause						: Delay;
		
	private	var loopMode				: Boolean		= false;
	private	var isPlaying				: Boolean 	= false;
	private	var isDragging			: Boolean 	= false;
	private	var isVolChanging		: Boolean 	= false;
	private	var showVolume			: Boolean		= false;
	private	var lastDragPer			: Number 		= 0;
	                          
	private	var grad						: MovieClip;
	
	private	var loadFailed			: Boolean	= false;

	
	
	private function init( Void ) : Void
	{
		barLoad._xscale = 0;
		barPos._xscale = 0;
		volumeBar._visible = false;
				
		_soundbuftime = 0;

		setStyles();
		
		Key.addListener( this );
	}
	
	
	private function onLoad( Void ) : Void
	{
		setListeners();	
	}
	
	
	private function prepareSound( Void ) : Void
	{
		createEmptyObject( "sndContainer", 0 );
		snd = new Sound( sndContainer );
		snd[ "owner" ] = this;
		snd.onLoad	= function( bFlag : Boolean ) { this.owner.onSoundLoaded( bFlag ); }
		snd.onSoundComplete = function() { this.owner.onSoundComplete(); }
	}
	
	
	private function setStyles( Void ) : Void
	{
		titleTxt.setStyle( "fontFamily", "Verdana" );
		titleTxt.setStyle( "fontSize", 9 );
		titleTxt.setStyle( "embedFonts", false );
		
		dlBtn.useHandCursor = false;
		toggleTimeBtn.useHandCursor = false;
	}
	
	
	private function setListeners( Void ) : Void
	{		
		dlBtn.onRelease 					= function() { this._parent.downloadTrack(); }
		toggleTimeBtn.onRelease 	= function() { this._parent.toggleTimeMode(); }
		loopBtn.addEventListener( "click", Delegate.create( this, toggleLoopMode ) );
	}
	
	
	private function onMouseUp( Void ) : Void
	{
		stopUpdatingVolume();
	
		if ( !isDragging )
			return;
	
		delete onEnterFrame;
	
		var xm = barLoad._xmouse / 100 * barLoad._xscale;
		jumpTo( lastDragPer );
		isDragging = false;
	}
	
	
	private function onMouseDown( Void ) : Void
	{
		if ( Key.isDown( Key.SHIFT ) )
			return;
	
		if ( !barLoad.hitTest( _root._xmouse, _root._ymouse ) )
			return;
		
		onEnterFrame = wind;
		isDragging = true;
	}
	
	
	public function setSound( url : String, txt : String, loop : String ) : Void
	{
		sndUrl = url;
		titleTxt.text = txt;		
		titleTxt.pause();
		pause = new Delay( titleTxt, "unpause", [], 3000 );
		pause.start();
		
		loopBtn.selected = loopMode = loop == "true";
		
		grad._visible = titleTxt.needsScroll;
	}
	
	
	private function onKeyDown( Void ) : Void
	{
		if ( !Key.isDown( Key.SHIFT ) || loadFailed  )
			return;
		
		setVolumeMode( true );
		
		if ( loadProgress < 100 )
			controlBtn.gotoAndStop( "unload" );
	}
	
	
	private function onKeyUp( Void ) : Void
	{
		if ( Key.getCode() != Key.SHIFT || loadFailed )
			return;
			
		setVolumeMode( false );
	
		if ( isPlaying )
			controlBtn.gotoAndStop( "pause" );
		else
			controlBtn.gotoAndStop( "play" );
			
		volumeBar._visible = false;
		delete volumeBarBtn.onPress;
	}
	
	
	private function startUpdatingVolume( Void ) : Void
	{
		onEnterFrame = updateVolume;
		isVolChanging = true;
	}
	
	
	private function setVolumeMode( bFlag : Boolean ) : Void
	{
		showVolume = bFlag;
	
		if ( bFlag )
		{
			volumeBarBtn.onPress = function() { _parent.startUpdatingVolume( ); }
			volumeBar._visible = true;
			volumeBarBtn.useHandCursor = false;
			showVolume = true;
			updateTimeTxt();
		}
		else
		{
			stopUpdatingVolume();
			updateTimeTxt();
		}
		
		barLoad._visible = barPos._visible = !showVolume;
	}
	
	
	private function updateVolume( Void ) : Void
	{
		var percent = volumeBarBtn._xmouse / ( volumeBarBtn._width / 100 );
		
		if ( percent < 0 ) percent = 0;
		else if ( percent > 100 ) percent = 100;
		
		snd.setVolume( percent );
		volumeBar._xscale = percent;
		vol = percent;
		updateTimeTxt();
	}
	
	
	private function stopUpdatingVolume( Void ) : Void
	{
		if ( !isVolChanging )
			return;
	
		delete onEnterFrame;
		isVolChanging = false;
		
		updateTimeTxt();		
	}
	
	
	private function updateStatus( Void ) : Void
	{
		var total 			= snd.getBytesTotal();
		var current		= snd.getBytesLoaded();
		var percent		= current / ( total / 100 );
		loadProgress		= percent;
		barLoad._xscale 	= Math.round( percent );

		updateTimeTxt();
		
		if ( !isPlaying )
			return;
		
		var posPercent	= snd.position / ( snd.duration / 100 );
		barPos._xscale	= barLoad._xscale / 100 * posPercent;
	}
	
	
	private function onSoundLoaded( bFlag : Boolean ) : Void
	{
		if ( bFlag )
			return;
		
		// Ladevorgang ist fehlgeschlagen
		loadFailed = true;
		controlBtn.gotoAndStop( "unload" );
		controlBtn.btn.enabled = false;
		setVolumeMode( false );
		titleTxt.text = "Nicht geladen!";
		dlBtn.enabled = false;
	}
	
	
	private function onSoundComplete( Void ) : Void
	{
		if ( loopMode )
		{
			lastPos = 0;
			playSound();
			return;
		}
		
		controlBtn.gotoAndStop( "play" );
		delete updateInt;
		updateTimeTxt( 0 );
		lastPos = 0;
		barPos._xscale = 0;
		snd.start();
		snd.stop();
	}
	
	
	private function playSound( Void ) : Void
	{
		if ( !soundLoaded )
		{
			prepareSound();		
			snd.loadSound( sndUrl, true );			
			soundLoaded = true;
			snd.setVolume( vol );
			updateInt = setInterval( this, "updateStatus", 250 );			
			return;
		}
	
		if ( lastPos != undefined || lastPos > snd.duration || lastPos < 0 )
			snd.start( lastPos );
		else
			snd.start();
	}
	
	
	private function pauseSound( Void ) : Void
	{
		lastPos = snd.position / 1000;
		snd.stop();
	}
	
	
	private function click( action : String ) : Void
	{
		if ( action == "play" )
		{
			playSound();
			isPlaying = true;			
		}
		else if ( action == "pause" )
		{
			pauseSound();
			isPlaying = false;			
		}
		else if ( action == "unload" )		
			unloadSound();
	}
	
	
	private function unloadSound( Void ) : Void
	{
		destroyObject( "sndContainer" );
		clearInterval( updateInt );
		updateTimeTxt( 0 );
		delete snd;
		
		soundLoaded 		= false;
		barLoad._xscale 	= 0;
		barPos._xscale 	= 0;
		isPlaying 			= false;
		loadProgress 		= 0;
	}
	
	
	private function downloadTrack( e : Object ) : Void
	{
		getURL( "javascript:mp3url(\"" + sndUrl + "\");"  );
	}
	
	
	private function updateTimeTxt( pos : Number ) : Void
	{
		if ( showVolume )
		{
			timeTxt.text = Math.round( vol ) + "%";
			return;
		}	
	
		if ( pos == undefined )
			pos = snd.position;
	
		var t = new Date();
		
		if ( !showTotalTime )
			t.setTime( pos );
		else
			t.setTime( snd.duration * (100 / loadProgress ) );
			
		if ( !soundLoaded )
			t.setTime( 0 );
			
		var mins 	= t.getMinutes();
		var secs 	= t.getSeconds();
		
		if ( mins < 10 ) mins = "0" + mins;
		if ( secs < 10 ) secs = "0" + secs;
		
		timeTxt.text = "(" + mins + ":" + secs + ")";	
	}
	
	
	private function toggleTimeMode( Void ) : Void
	{	
		showTotalTime = !showTotalTime;
		updateTimeTxt();
	}
	
	
	private function toggleLoopMode( Void ) : Void
	{
		loopMode = loopBtn.selected;
	}
	
	
	private function wind( Void ) : Void
	{
		var xm = barLoad._xmouse / 100 * barLoad._xscale;
		var percent = xm / ( barLoad._width / 100 );
		
		if ( percent < 0 ) percent = 0;
		else if ( percent > 100 ) percent = 100;		
		
		lastDragPer = percent;
		var pos = Math.round( snd.duration / 100 * percent / 1000 );
		barPos._xscale = barLoad._xscale / 100 * percent;
		lastPos = pos;
		updateTimeTxt( pos * 1000 );
	}
	
	
	private function jumpTo( percent : Number ) : Void
	{
		if ( percent < 0 ) percent = 0;
		else if ( percent > 100 ) percent = 100;
	
		barPos._xscale = barLoad._xscale / 100 * percent;
		var pos = Math.round( snd.duration / 100 * percent / 1000 );
		lastPos = pos;
		updateTimeTxt( pos * 1000 );
		
		if ( !isPlaying )
			return;
			
		snd.stop();
		playSound();
	}
}